import Foundation
import CoreLocation

// MARK: - 苹果地理编码服务

class AppleGeocodingService {
    static let shared = AppleGeocodingService()
    
    private let geocoder = CLGeocoder()
    
    private init() {}
    
    // MARK: - 地址信息结构
    
    struct AppleLocationAddressInfo {
        let name: String?
        let thoroughfare: String?
        let subThoroughfare: String?
        let locality: String?
        let subLocality: String?
        let administrativeArea: String?
        let subAdministrativeArea: String?
        let postalCode: String?
        let country: String?
        let isoCountryCode: String?
        let areasOfInterest: [String]? // 🎯 新增：兴趣点信息
        
        var displayName: String {
            // 🎯 优先显示兴趣点名称（POI）
            if let areasOfInterest = areasOfInterest, !areasOfInterest.isEmpty {
                return areasOfInterest.first!
            }
            
            if let name = name, !name.isEmpty {
                return name
            }
            return formattedAddress
        }
        
        var formattedAddress: String {
            var parts: [String] = []
            
            if let thoroughfare = thoroughfare {
                parts.append(thoroughfare)
            }
            
            if let subLocality = subLocality {
                parts.append(subLocality)
            }
            
            if let locality = locality {
                parts.append(locality)
            }
            
            if let administrativeArea = administrativeArea {
                parts.append(administrativeArea)
            }
            
            if let country = country {
                parts.append(country)
            }
            
            return parts.isEmpty ? "未知地址" : parts.joined(separator: ", ")
        }
        
        var cityName: String {
            return locality ?? administrativeArea ?? "未知城市"
        }
        
        var countryName: String {
            return country ?? "未知国家"
        }
        
        var streetName: String {
            return thoroughfare ?? "未知街道"
        }
        
        // 🎯 新增：获取POI名称
        var poiName: String? {
            return areasOfInterest?.first
        }
    }
    
    // MARK: - 逆地理编码（坐标转地址）
    
    /// 根据坐标获取地址信息
    /// - Parameters:
    ///   - latitude: 纬度
    ///   - longitude: 经度
    ///   - completion: 完成回调，返回地址信息或nil
    func fetchAddressInfo(latitude: Double, longitude: Double, completion: @escaping (AppleLocationAddressInfo?) -> Void) {
        let location = CLLocation(latitude: latitude, longitude: longitude)
        
        print("📍 开始苹果地理编码: [\(latitude), \(longitude)]")
        
        geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
            // 检查错误
            if let error = error {
                print("❌ 苹果地理编码失败: \(error.localizedDescription)")
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            // 检查是否有地标信息
            guard let placemarks = placemarks, !placemarks.isEmpty else {
                print("📍 苹果地理编码未找到地址信息")
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            // 使用第一个（最相关）的地标
            let placemark = placemarks.first!
            
            // 创建地址信息对象
            let addressInfo = AppleLocationAddressInfo(
                name: placemark.name,
                thoroughfare: placemark.thoroughfare,
                subThoroughfare: placemark.subThoroughfare,
                locality: placemark.locality,
                subLocality: placemark.subLocality,
                administrativeArea: placemark.administrativeArea,
                subAdministrativeArea: placemark.subAdministrativeArea,
                postalCode: placemark.postalCode,
                country: placemark.country,
                isoCountryCode: placemark.isoCountryCode,
                areasOfInterest: placemark.areasOfInterest // 🎯 新增：包含兴趣点信息
            )
            
            print("📍 苹果地理编码成功: \(addressInfo.cityName) - \(addressInfo.displayName)")
            
            DispatchQueue.main.async {
                completion(addressInfo)
            }
        }
    }
    
    // MARK: - 地理编码（地址转坐标）
    
    /// 根据地址获取坐标
    /// - Parameters:
    ///   - address: 地址字符串
    ///   - completion: 完成回调，返回坐标或nil
    func fetchCoordinates(address: String, completion: @escaping (CLLocationCoordinate2D?) -> Void) {
        print("📍 开始苹果地址编码: \(address)")
        
        geocoder.geocodeAddressString(address) { (placemarks, error) in
            // 检查错误
            if let error = error {
                print("❌ 苹果地址编码失败: \(error.localizedDescription)")
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            // 检查是否有地标信息
            guard let placemarks = placemarks, !placemarks.isEmpty else {
                print("📍 苹果地址编码未找到坐标信息")
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            // 使用第一个（最相关）的地标
            let placemark = placemarks.first!
            
            if let location = placemark.location {
                print("📍 苹果地址编码成功: \(location.coordinate)")
                DispatchQueue.main.async {
                    completion(location.coordinate)
                }
            } else {
                print("📍 苹果地址编码未找到有效坐标")
                DispatchQueue.main.async {
                    completion(nil)
                }
            }
        }
    }
    
    // MARK: - 异步版本
    
    /// 异步版本的地址信息获取方法
    /// - Parameters:
    ///   - latitude: 纬度
    ///   - longitude: 经度
    /// - Returns: 地址信息或nil
    func fetchAddressInfoAsync(latitude: Double, longitude: Double) async -> AppleLocationAddressInfo? {
        return await withCheckedContinuation { continuation in
            fetchAddressInfo(latitude: latitude, longitude: longitude) { addressInfo in
                continuation.resume(returning: addressInfo)
            }
        }
    }
    
    /// 异步版本的坐标获取方法
    /// - Parameters:
    ///   - address: 地址字符串
    /// - Returns: 坐标或nil
    func fetchCoordinatesAsync(address: String) async -> CLLocationCoordinate2D? {
        return await withCheckedContinuation { continuation in
            fetchCoordinates(address: address) { coordinate in
                continuation.resume(returning: coordinate)
            }
        }
    }
    
    // MARK: - 批量处理
    
    /// 批量获取地址信息
    /// - Parameter coordinates: 坐标数组
    /// - Returns: 坐标到地址信息的映射
    func fetchAddressInfoBatch(coordinates: [(CLLocationCoordinate2D, String)]) async -> [CLLocationCoordinate2D: AppleLocationAddressInfo] {
        var results: [CLLocationCoordinate2D: AppleLocationAddressInfo] = [:]
        
        // 使用任务组控制并发数量
        await withTaskGroup(of: (CLLocationCoordinate2D, AppleLocationAddressInfo?).self) { group in
            for (coordinate, _) in coordinates {
                group.addTask {
                    // 添加延迟避免API限制
                    try? await Task.sleep(nanoseconds: 200_000_000) // 200ms
                    
                    let addressInfo = await self.fetchAddressInfoAsync(
                        latitude: coordinate.latitude,
                        longitude: coordinate.longitude
                    )
                    
                    return (coordinate, addressInfo)
                }
            }
            
            // 限制并发数量为2（苹果服务限制较严格）
            var activeTasks = 0
            let maxConcurrentTasks = 2
            
            for await (coordinate, addressInfo) in group {
                if let addressInfo = addressInfo {
                    results[coordinate] = addressInfo
                }
                
                activeTasks += 1
                if activeTasks >= maxConcurrentTasks {
                    // 等待一些任务完成
                    try? await Task.sleep(nanoseconds: 500_000_000) // 500ms
                    activeTasks = max(0, activeTasks - 1)
                }
            }
        }
        
        return results
    }
} 